/* ========================================================================
 * Copyright 2012 Katsushige Nakanishi (kat.nakanishi@gmail.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ========================================================================
 */

package com.android.deviceapi.audio;

import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import android.content.Context;
import android.database.Cursor;
import android.provider.MediaStore;
import android.util.Log;

import com.android.deviceapi.DeviceApi;
import com.android.deviceapi.audio.object.Album;
import com.android.deviceapi.audio.object.Albums;
import com.android.deviceapi.audio.object.Artist;
import com.android.deviceapi.audio.object.Artists;
import com.android.deviceapi.audio.object.Track;
import com.android.deviceapi.audio.object.Tracks;
import com.android.deviceapi.common.Constants;
import com.google.gson.Gson;

/**
 * "/deviceapi/audio/tracks" "/deviceapi/audio/track/<track-id>"
 * "/deviceapi/audio/albums" "/deviceapi/audio/album/<album-id>"
 * "/deviceapi/audio/artists" "/deviceapi/audio/artist/<artist-id>"
 * "/deviceapi/audio/artist/<artist-id>/albums"
 * "/deviceapi/audio/artist/<artist-id>/album/<album-id>"
 */
public class AudioServlet extends HttpServlet {
    private static final boolean DEBUG = true;

    /**
     * 
     */
    private static final long serialVersionUID = 2107096566492478456L;

    private Context mContext;

    private Gson mGson;

    public AudioServlet(Context context) {
        mContext = context;
        mGson = new Gson();
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
            IOException {
        String pathInfo = req.getPathInfo();
        if (DEBUG)
            Log.d(Constants.TAG, "pathInfo: " + pathInfo);
        if (DeviceApi.Path.TRACKS.equals(pathInfo)) {
            Tracks tracks = getTracks();
            String json = mGson.toJson(tracks);
            resp.setStatus(HttpServletResponse.SC_OK);
            resp.setContentType("text/javascript; charset=UTF-8");
            Writer writer = resp.getWriter();
            writer.write(json);
            writer.flush();
            return;
        } else if (DeviceApi.Path.ALBUMS.equals(pathInfo)) {
            Albums albums = getAlbums();
            String json = mGson.toJson(albums);
            resp.setStatus(HttpServletResponse.SC_OK);
            resp.setContentType("text/javascript; charset=UTF-8");
            Writer writer = resp.getWriter();
            writer.write(json);
            writer.flush();
            return;
        } else if (DeviceApi.Path.ARTISTS.equals(pathInfo)) {
            Artists artists = getArtists();
            String json = mGson.toJson(artists);
            resp.setStatus(HttpServletResponse.SC_OK);
            resp.setContentType("text/javascript; charset=UTF-8");
            Writer writer = resp.getWriter();
            writer.write(json);
            writer.flush();
            return;
        }
        resp.sendError(HttpServletResponse.SC_BAD_REQUEST);
    }

    private Tracks getTracks() {
        Tracks tracks = new Tracks();
        String[] projection = new String[] {
                MediaStore.Audio.Media._ID, MediaStore.Audio.Media.TITLE,
                MediaStore.Audio.Media.ALBUM, MediaStore.Audio.Media.ARTIST
        };
        String sortOrder = MediaStore.Audio.Media.TITLE;
        Cursor c = mContext.getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
                projection, null, null, sortOrder);
        if (c != null) {
            int count = c.getCount();
            if (count > 0) {
                tracks.tracks = new ArrayList<Track>();
                final int ID_IDX = c.getColumnIndex(MediaStore.Audio.Media._ID);
                final int TITLE_IDX = c.getColumnIndex(MediaStore.Audio.Media.TITLE);
                final int ALBUM_IDX = c.getColumnIndex(MediaStore.Audio.Media.ALBUM);
                final int ARTIST_IDX = c.getColumnIndex(MediaStore.Audio.Media.ARTIST);
                for (int i = 0; i < count; i++) {
                    c.moveToPosition(i);
                    Track track = new Track();
                    track.id = c.getLong(ID_IDX);
                    track.title = c.getString(TITLE_IDX);
                    track.album = c.getString(ALBUM_IDX);
                    track.artist = c.getString(ARTIST_IDX);
                    tracks.tracks.add(track);
                }
            }
            c.close();
            c = null;
        }
        return tracks;
    }

    private Albums getAlbums() {
        Albums albums = new Albums();
        String[] projection = new String[] {
                MediaStore.Audio.Albums._ID,  MediaStore.Audio.Albums.ALBUM, MediaStore.Audio.Albums.ARTIST,
        };
        String sortOrder = MediaStore.Audio.Albums.ALBUM;
        Cursor c = mContext.getContentResolver().query(MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI,
                projection, null, null, sortOrder);
        if (c != null) {
            int count = c.getCount();
            if (count > 0) {
                albums.albums = new ArrayList<Album>();
                final int ID_IDX = c.getColumnIndex(MediaStore.Audio.Albums._ID);
                final int ALBUM_IDX = c.getColumnIndex(MediaStore.Audio.Albums.ALBUM);
                final int ARTIST_IDX = c.getColumnIndex(MediaStore.Audio.Albums.ARTIST);
                for (int i = 0; i < count; i++) {
                    c.moveToPosition(i);
                    Album album = new Album();
                    album.id = c.getLong(ID_IDX);
                    album.album = c.getString(ALBUM_IDX);
                    album.artist = c.getString(ARTIST_IDX);
                    albums.albums.add(album);
                }
            }
            c.close();
            c = null;
        }
        return albums;
    }
    
    private Artists getArtists() {
        Artists artists = new Artists();
        String[] projection = new String[] {
                MediaStore.Audio.Artists._ID,  MediaStore.Audio.Artists.ARTIST,
        };
        String sortOrder = MediaStore.Audio.Artists.ARTIST;
        Cursor c = mContext.getContentResolver().query(MediaStore.Audio.Artists.EXTERNAL_CONTENT_URI,
                projection, null, null, sortOrder);
        if (c != null) {
            int count = c.getCount();
            if (count > 0) {
                artists.artists = new ArrayList<Artist>();
                final int ID_IDX = c.getColumnIndex(MediaStore.Audio.Artists._ID);
                final int ARTIST_IDX = c.getColumnIndex(MediaStore.Audio.Artists.ARTIST);
                for (int i = 0; i < count; i++) {
                    c.moveToPosition(i);
                    Artist artist = new Artist();
                    artist.id = c.getLong(ID_IDX);
                    artist.artist = c.getString(ARTIST_IDX);
                    artists.artists.add(artist);
                }
            }
            c.close();
            c = null;
        }
        return artists;
    }
}
